﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ShoppingList
{
    public class ListViewModel : INotifyPropertyChanged
    {
        public enum MailContent
        {
            All,
            Cart,
            List
        }

        public ListViewModel()
        {
        }

        public ListViewModel(string name)
        {
            this.ItemsOnList = new ObservableCollection<ItemViewModel>();
            this.ItemsInCart = new ObservableCollection<ItemViewModel>();
            this.Name = name;
            this.Date = DateTime.Now;
        }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ItemViewModel> ItemsOnList { get; set; }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<ItemViewModel> ItemsInCart { get; set; }

        private string _name;

        /// <summary>
        /// Gets or sets the name of list.
        /// </summary>
        /// <value>The name of list.</value>
        public string Name
        {
            get
            {
                return this._name;
            }

            set
            {
                if (value != this._name)
                {
                    this._name = value;

                    this.OnPropertyChanged("Name");
                }
            }
        }

        private DateTime _date;

        /// <summary>
        /// Gets or sets the Date.
        /// </summary>
        /// <value>The Date.</value>
        public DateTime Date
        {
            get
            {
                return this._date;
            }

            set
            {
                if (value != this._date)
                {
                    this._date = value;

                    this.OnPropertyChanged("Date");
                }
            }
        }

        bool _selected;

        /// <summary>
        /// Gets or sets the selected.
        /// </summary>
        /// <value>The selected.</value>
        public bool Selected
        {
            get
            {
                return this._selected;
            }

            set
            {
                if (value != this._selected)
                {
                    this._selected = value;

                    this.OnPropertyChanged("Selected");
                }
            }
        }

        private ItemViewModel _currentItem;

        /// <summary>
        /// Gets or sets the current item.
        /// </summary>
        /// <value>The current item.</value>
        [System.Xml.Serialization.XmlIgnore]
        public ItemViewModel CurrentItem
        {
            get { return _currentItem; }
            set
            {
                if (_currentItem != null)
                {
                    _currentItem.Selected = false;
                }
                _currentItem = value;
                if (_currentItem != null)
                {
                    _currentItem.Selected = true;
                    if (ItemsInCart != null)
                    {
                        foreach (var item in ItemsInCart)
                        {
                            item.Selected = item == value;
                        }
                    }
                    if (ItemsOnList != null)
                    {
                        foreach (var item in ItemsOnList)
                        {
                            item.Selected = item == value;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets the cart sum.
        /// </summary>
        /// <value>The cart sum.</value>
        [System.Xml.Serialization.XmlIgnore]
        public decimal CartSum
        {
            get
            {
                var res = new decimal(0);
                if (ItemsInCart != null)
                {
                    foreach (var item in this.ItemsInCart)
                    {
                        res += item.Price * item.Amount;
                    }
                }
                return res;
            }
        }

        /// <summary>
        /// Gets or sets the cart sum.
        /// </summary>
        /// <value>The cart sum.</value>
        [System.Xml.Serialization.XmlIgnore]
        public decimal ListSum
        {
            get
            {
                var res = new decimal(0);
                if (ItemsOnList != null)
                {
                    foreach (var item in this.ItemsOnList)
                    {
                        res += item.Price * item.Amount;
                    }
                }
                return res;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        internal void OnPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void TransferItem(ItemViewModel item)
        {
            if (this.ItemsInCart.Contains(item))
            {
                this.ItemsInCart.Remove(item);
                this.ItemsOnList.Add(item);
            }
            else if (this.ItemsOnList.Contains(item))
            {
                this.ItemsOnList.Remove(item);
                this.ItemsInCart.Add(item);
            }
            OnPropertyChanged("CartSum");
            OnPropertyChanged("ListSum");
            this.Date = DateTime.Now;
        }

        //public void SendViaEmail(bool chooseRecipientFirst = false, MailContent content = MailContent.All)
        //{
        //    if (chooseRecipientFirst)
        //    {
        //        Microsoft.Phone.Tasks.EmailAddressChooserTask eact = new Microsoft.Phone.Tasks.EmailAddressChooserTask();
        //        eact.Completed += new EventHandler<Microsoft.Phone.Tasks.EmailResult>(eact_Completed);
        //        eact.Show();
        //    }
        //    else
        //    {
        //        SendViaEmail(string.Empty, content);
        //    }
        //}

        //void eact_Completed(object sender, Microsoft.Phone.Tasks.EmailResult e)
        //{
        //    if (e.TaskResult == Microsoft.Phone.Tasks.TaskResult.OK)
        //    {
        //        SendViaEmail(e.Email);
        //    }
        //}

        public void SendViaEmail(string to = null, MailContent content = MailContent.All)
        {
            Microsoft.Phone.Tasks.EmailComposeTask ect = new Microsoft.Phone.Tasks.EmailComposeTask();
            if (!string.IsNullOrEmpty(to)) ect.To = to;
            ect.Subject = String.Format(Resources.Mail_ShoppingListSubject, this.Name);
            StringBuilder body = new StringBuilder();
            if (content == MailContent.All || content == MailContent.List)
            {
                foreach (var item in ItemsOnList)
                {
                    if (item.ItemName.Length >= MailPadding) MailPadding = item.ItemName.Length + 5;
                }
                body.AppendFormat("{0}:", Resources.Mail_ShoppingListItemsOnList).AppendLine();
                body.AppendLine(MailItemsLegend);
                foreach (var item in ItemsOnList)
                {
                    body.AppendLine(CreateLineForItemInMail(item));
                }
                body.AppendLine(string.Format("Total:{0}", this.ListSum.ToString("n2").PadLeft(MailPadding + 20)));
                body.AppendLine();
            }
            if (content == MailContent.All || content == MailContent.Cart)
            {
                foreach (var item in ItemsInCart)
                {
                    if (item.ItemName.Length >= MailPadding) MailPadding = item.ItemName.Length + 5;
                }
                body.AppendFormat("{0}:", Resources.Mail_ShoppingListItemsNotOnList).AppendLine();
                body.AppendLine(MailItemsLegend);
                foreach (var item in ItemsInCart)
                {
                    body.AppendLine(CreateLineForItemInMail(item));
                }
                body.AppendLine(string.Format("Total:{0}", this.CartSum.ToString("n2").PadLeft(MailPadding + 20)));
                body.AppendLine();
            }

            body.AppendLine(Resources.Mail_FootNote);
            ect.Body = body.ToString();
            ect.Show();
        }

        [System.Xml.Serialization.XmlIgnore]
        private int MailPadding = 30;

        private string CreateLineForItemInMail(ItemViewModel item)
        {
            string line = string.Format("-{0}  x  {1} {2} {3}", item.Amount.ToString("n2").PadLeft(6, ' '), item.ItemName.PadRight(MailPadding), item.Price.ToString("n2").PadLeft(6), item.Sum.PadLeft(6));
            return line;
        }

        [System.Xml.Serialization.XmlIgnore]
        private string MailItemsLegend
        {
            get
            {
                return string.Format("  {0}    {1}  {2}  {3}", "Amount".ToString().PadLeft(6, ' '), "Item Name".PadRight(MailPadding), "Price", "Total");
            }
        }
    }
}